package ixRedis

import (
	"errors"
	"time"
)

// Config Redis 配置
type Config struct {
	// 服务器地址
	Host string
	// 端口
	Port int
	// 密码
	Password string
	// 数据库编号
	DB int
	// 键前缀
	KeyPrefix string
	// 最大空闲连接数
	MaxIdle int
	// 最大活跃连接数
	MaxActive int
	// 连接空闲超时时间
	IdleTimeout time.Duration
	// 连接超时时间
	ConnectTimeout time.Duration
	// 读取超时时间
	ReadTimeout time.Duration
	// 写入超时时间
	WriteTimeout time.Duration
	// 是否等待连接池耗尽
	Wait bool
}

// DefaultConfig 默认配置
func DefaultConfig() *Config {
	return &Config{
		Host:           "localhost",
		Port:           6379,
		Password:       "",
		DB:             0,
		KeyPrefix:      "",
		MaxIdle:        10,
		MaxActive:      100,
		IdleTimeout:    300 * time.Second,
		ConnectTimeout: 5 * time.Second,
		ReadTimeout:    3 * time.Second,
		WriteTimeout:   3 * time.Second,
		Wait:           true,
	}
}

// WithPassword 设置密码选项
func WithPassword(password string) func(*Config) {
	return func(c *Config) {
		c.Password = password
	}
}

// WithDB 设置数据库选项
func WithDB(db int) func(*Config) {
	return func(c *Config) {
		c.DB = db
	}
}

// WithMaxIdle 设置最大空闲连接数选项
func WithMaxIdle(maxIdle int) func(*Config) {
	return func(c *Config) {
		c.MaxIdle = maxIdle
	}
}

// WithMaxActive 设置最大活跃连接数选项
func WithMaxActive(maxActive int) func(*Config) {
	return func(c *Config) {
		c.MaxActive = maxActive
	}
}

// WithTimeout 设置超时选项
func WithTimeout(connectTimeout, readTimeout, writeTimeout time.Duration) func(*Config) {
	return func(c *Config) {
		c.ConnectTimeout = connectTimeout
		c.ReadTimeout = readTimeout
		c.WriteTimeout = writeTimeout
	}
}

// WithIdleTimeout 设置空闲超时选项
func WithIdleTimeout(idleTimeout time.Duration) func(*Config) {
	return func(c *Config) {
		c.IdleTimeout = idleTimeout
	}
}

// WithWait 设置等待选项
func WithWait(wait bool) func(*Config) {
	return func(c *Config) {
		c.Wait = wait
	}
}

// WithKeyPrefix 设置键前缀选项
func WithKeyPrefix(prefix string) func(*Config) {
	return func(c *Config) {
		c.KeyPrefix = prefix
	}
}

// Validate 验证配置
func (c *Config) Validate() error {
	if c.Host == "" {
		return errors.New("host cannot be empty")
	}
	if c.Port <= 0 || c.Port > 65535 {
		return errors.New("port must be between 1 and 65535")
	}
	if c.DB < 0 || c.DB > 15 {
		return errors.New("database must be between 0 and 15")
	}
	if c.MaxIdle < 0 {
		return errors.New("max idle connections cannot be negative")
	}
	if c.MaxActive < 0 {
		return errors.New("max active connections cannot be negative")
	}
	if c.MaxIdle > c.MaxActive {
		return errors.New("max idle connections cannot be greater than max active connections")
	}
	return nil
}

// Clone 克隆配置
func (c *Config) Clone() *Config {
	return &Config{
		Host:           c.Host,
		Port:           c.Port,
		Password:       c.Password,
		DB:             c.DB,
		KeyPrefix:      c.KeyPrefix,
		MaxIdle:        c.MaxIdle,
		MaxActive:      c.MaxActive,
		IdleTimeout:    c.IdleTimeout,
		ConnectTimeout: c.ConnectTimeout,
		ReadTimeout:    c.ReadTimeout,
		WriteTimeout:   c.WriteTimeout,
		Wait:           c.Wait,
	}
}
